package com.cs.service.impl;

import com.cs.dto.EvaluateDetailDto;
import com.cs.dto.EvaluateDto;
import com.cs.dto.ModelDto;
import com.cs.mapper.MalfunctionMapper;
import com.cs.mapper.MalfunctionOptionsMapper;
import com.cs.entity.*;
import com.cs.mapper.EvaluateMapper;
import com.cs.service.EvaluateDetailService;
import com.cs.service.EvaluateService;
import com.cs.service.ModelService;
import com.cs.utils.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 评估信息 服务实现类
 * </p>
 *
 * @author qf
 * @since 2021-08-04
 */
@Service
public class EvaluateServiceImpl extends ServiceImpl<EvaluateMapper, Evaluate> implements EvaluateService {

    @Autowired
    private MalfunctionOptionsMapper optionsMapper;
    @Autowired
    private MalfunctionMapper malfunctionMapper;
    @Autowired
    private EvaluateDetailService evaluateDetailService; // 评估详情
    @Autowired
    private ModelService modelService;


    @Override
    public Evaluate assess(Long modelId, String optionIds, Long id) {
        /**
         * id":
         * "modelId":
         * "price": 1000,   总金额 = 所有单个故障的金额相加
         *                  单个故障的金额 = 最高价(malfunction.maintainTopPrice) * 百分比(malfunction_options.ratio)
         * "subscription":  定金
         */

        // 评估详情 - 多个，因为故障点有多个
        List<MalfunctionOptions> optionList = new ArrayList<>();

        // 总金额，默认是0
        BigDecimal totalPrice = new BigDecimal(0);
        Evaluate evaluate = null;


        // 1.将optionsId变成一个集合
        Set<Long> optIds = StringUtil.string2LongSet(optionIds, ",");
        // 2.遍历这个集合
        for (Long optId : optIds) {
            // 1.根据故障字典id获取故障字典对象
            MalfunctionOptions option = optionsMapper.selectById(optId);
            // 将这个对象放入集合中，后面会使用这个对象保存评估详细信息
            optionList.add(option);
            // 2.获取故障id
            Long malfId = option.getMalfId();
            // 3.通过故障id获取最高的维修价格，先要获取故障对象
            Malfunction malfunction = malfunctionMapper.selectById(malfId);
            // 以后在工作中，涉及到钱的都需要使用BigDecimal
            BigDecimal topPrice = malfunction.getMaintainTopPrice();
            // ratio 百分比
            Integer ratio = option.getRatio();
            // 单个故障详情的维修价格
            // topPrice.multiply(new BigDecimal(ratio * 0.01)); 400(topPrice) *(multiply) 1(new BigDecimal(ratio * 0.01))
            BigDecimal onePrice = topPrice.multiply(new BigDecimal(ratio * 0.01));
            // 将单个价格添加到总价格内
            totalPrice = totalPrice.add(onePrice);
        }
        // 订单的金额
        BigDecimal subscription = totalPrice.multiply(new BigDecimal(0.1));
        evaluate = new Evaluate();
        evaluate.setModelId(modelId);
        evaluate.setPrice(totalPrice);
        evaluate.setSubscription(subscription);
        evaluate.setCreatedUserId(id);
        // 保存evaluate对象
        this.save(evaluate);
        // 保存评估详细信息
        evaluateDetailService.saveBatchByOptions(evaluate.getId(), optionList);
        return evaluate;
    }

    @Override
    public EvaluateDto assessInfo(Long id) {
        EvaluateDto evaluateDto = new EvaluateDto();
        // 1.获取评估对象 - 根据评估id获取评估对象
        Evaluate evaluate = this.getById(id);
        // 这个方法就是将一个对象中属性的值copy给另一个对象，条件是属性名相同
        // 第一个参数是源数据 第二个是目标数据
        BeanUtils.copyProperties(evaluate, evaluateDto);
        // 2.获取商品对象
        Long modelId = evaluateDto.getModelId();
        Model model = modelService.getById(modelId);
        ModelDto modelDto = new ModelDto();
        BeanUtils.copyProperties(model, modelDto);
        // 拼接oss的图片地址
        modelService.formatModel(modelDto);
        // 3.评估详情
        // 根据评估id获取评估详情的集合
        QueryWrapper<EvaluateDetail> wrapper = new QueryWrapper<>();
        wrapper.eq("evaluateId", id);
        // 评估详情集合
        List<EvaluateDetail> detailList = evaluateDetailService.list(wrapper);
        // 新建一个detailDto的集合
        List<EvaluateDetailDto> detailDtoList = new ArrayList<>();
        // 遍历评估详情集合，将中间的对象改成对应的DTO对象
//        detailList.forEach(evaluateDetail -> {
//            // 创建一个dto对象
//            EvaluateDetailDto detailDto = new EvaluateDetailDto();
//            BeanUtils.copyProperties(evaluateDetail, detailDto);
//            detailDtoList.add(detailDto);
//        });

        for (EvaluateDetail evaluateDetail : detailList) {
            // 创建一个dto对象
            EvaluateDetailDto detailDto = new EvaluateDetailDto();
            // 给dto对象赋值
            BeanUtils.copyProperties(evaluateDetail, detailDto);
            // 将dto对象添加到集合中
            detailDtoList.add(detailDto);
        }

        evaluateDto.setModel(modelDto);
        evaluateDto.setDetailList(detailDtoList);

        return evaluateDto;
    }
}
